package cn.yto.print.controller;

import cn.yto.print.config.ThreadPoolManager;
import cn.yto.print.utils.CommonUtil;
import de.felixroske.jfxsupport.FXMLController;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ResourceBundle;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
@FXMLController
public class LoggerController extends BaseController implements Initializable {

    private static final String LOGFILE = "logs/ytzs.log";

    private static ScheduledExecutorService executor;
    private long lastLogFilePos = 0L;

    @FXML
    private TextArea logTextArea;

    /**
     * 初始化窗口事件
     */
    public void initializeStage(Stage stage) {
        if (stage == null) {
            log.error("打开调试日志窗口未初始化");
            return;
        }
        stage.setOnCloseRequest(event -> CommonUtil.gracefulShutdown(executor));
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // 创建日志文件对象
        File logFile = new File(LOGFILE);
        startLogReadingProcess(logFile);
    }

    /**
     * 启动日志文件的实时读取
     */
    private void startLogReadingProcess(File logFile) {
        initializeLogFilePointer(logFile);
        if (executor == null || executor.isShutdown() || executor.isTerminated()) {
            executor = ThreadPoolManager.getSingleScheduledExecutor();
        }
        executor.scheduleAtFixedRate(() -> {
            readAndAppendLogContent(logFile);
        }, 0, 500, TimeUnit.MILLISECONDS);
    }

    private void initializeLogFilePointer(File logFile) {
        try (RandomAccessFile raf = new RandomAccessFile(logFile, "r")) {
            long totalLength = raf.length();
            long startingPoint = totalLength > 1000 ? totalLength - 1000 : 0;
            raf.seek(startingPoint);
            lastLogFilePos = raf.getFilePointer();
        } catch (IOException ex) {
            log.error("初始化调试日志读取位置异常", ex);
        }
    }

    private void readAndAppendLogContent(File logFile) {
        try (RandomAccessFile raf = new RandomAccessFile(logFile, "r")) {
            long currentFileLength = raf.length();
            if (currentFileLength < lastLogFilePos) {
                lastLogFilePos = 0L; // 从头开始
            }
            raf.seek(lastLogFilePos);
            // 循环读取每一行新增内容
            String line;
            while ((line = raf.readLine()) != null) {
                final String output = new String(
                        line.getBytes(StandardCharsets.ISO_8859_1),
                        StandardCharsets.UTF_8
                );
                Platform.runLater(() -> logTextArea.appendText(output + "\n"));
            }
            lastLogFilePos = raf.getFilePointer();
        } catch (IOException ex) {
            log.error("调试日志读取异常", ex);
        }
    }

}
